#include "sdlengine.hpp"
#include "bresenham/bresenham.hpp"
#include "unittest.hpp"
#include "fmt.hpp"

constexpr int GridSize = 50;

using namespace sdl_engine::log;
using namespace sdl_engine::unit_test;
using namespace sdl_engine::component::graphics;

class BresenhamTest: public Test, public sdl_engine::App {
public:
    void SetUp() override {
        sdl_engine::engine.SetApp(this);
    }

    void Init() override {
        sdl_engine::engine.SetClearColor(sdl_engine::color(0, 0, 0));
    }

    void OnMouseMotion(const sdl_engine::EventMouseMotion& motion) override {
        mousePoint_ = motion.Position();
    }

    void Run() override {
        RUN_ENGINE();
    }

    void Render(sdl_engine::Renderer& render) override {
        auto& window = sdl_engine::engine.GetWindow();

        Bresenham bresenham(
                      sdl_engine::point(window.GetSize().w / (2 * GridSize),
                                        window.GetSize().h / (2 * GridSize)),
                      sdl_engine::point(mousePoint_.x / GridSize,
                                        mousePoint_.y / GridSize));

        render.SetDrawColor(sdl_engine::color(0, 255, 0));
        sdl_engine::Rect rect(
            sdl_engine::point(bresenham.CurPoint().x * GridSize,
                  bresenham.CurPoint().y * GridSize),
            sdl_engine::size(GridSize, GridSize)
        );
        render.RenderFillRect(rect);
        do {
            bresenham.Step();
            auto point = bresenham.CurPoint();
            point.x *= GridSize;
            point.y *= GridSize;
            rect = {point.x, point.y, GridSize, GridSize};
            render.RenderFillRect(rect);
        } while (!bresenham.IsFinished());

        sdl_engine::engine.GetInnerBmpFont().Render(
            "MOVE YOUR MOUSE TO CHECK THE LINE", 16,
            sdl_engine::point(100, 100), sdl_engine::color(255, 255, 0)
        );
    }

private:
    sdl_engine::Point mousePoint_;
};

int main(int argc, char** argv) {
    sdl_engine::Window::CreateInfo windowInfo;
    windowInfo.SetTitle("test bresenham")
              .SetSize(sdl_engine::size(720, 480));

    auto bresenhamTest = new BresenhamTest;

    sdl_engine::engine.Init(
        argc, argv,
        windowInfo,
        sdl_engine::Renderer::CreateInfo()
    );

    unittest.RegistTest(bresenhamTest);
    unittest.AddTest(bresenhamTest);

    unittest.RunTests();

    sdl_engine::engine.Shutdown();
    return 0;
}
